﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace zijian666.DI;

[TestClass]
public class 命名多生命周期注入测试
{
    [TestMethod]
    public void 没有瞬态服务()
    {
        var services = new ServiceCollection()
            .AddComponents([typeof(MyClass1)])
            .AddAutowired()
            .BuildServiceProvider();
        using (var scope = services.CreateScope())
        {
            var a = services.GetService<MyClass>();
            var b = scope.ServiceProvider.GetService<MyClass>();
            var c = services.GetService<MyClass>();
            var d = scope.ServiceProvider.GetService<MyClass>();
            Assert.AreNotEqual(a, b);
            Assert.AreEqual(a, c);
            Assert.AreEqual(b, d);
            Assert.IsTrue(a.IsRoot);
            Assert.IsFalse(b.IsRoot);

            var a1 = services.GetKeyedService<MyClass>("1");
            var b1 = scope.ServiceProvider.GetKeyedService<MyClass>("1");
            var c1 = services.GetKeyedService<MyClass>("1");
            var d1 = scope.ServiceProvider.GetKeyedService<MyClass>("1");
            Assert.AreNotEqual(a1, b1);
            Assert.AreEqual(a1, c1);
            Assert.AreEqual(b1, d1);
            Assert.IsTrue(a1.IsRoot);
            Assert.IsFalse(b1.IsRoot);

            var a2 = services.GetKeyedService<MyClass>("2");
            var b2 = scope.ServiceProvider.GetKeyedService<MyClass>("2");
            var c2 = services.GetKeyedService<MyClass>("2");
            var d2 = scope.ServiceProvider.GetKeyedService<MyClass>("2");
            Assert.AreNotEqual(a2, b2);
            Assert.AreEqual(a2, c2);
            Assert.AreEqual(b2, d2);
            Assert.IsTrue(a2.IsRoot);
            Assert.IsFalse(b2.IsRoot);

            Assert.AreNotEqual(a, a1);
            Assert.AreNotEqual(b, b1);
            Assert.AreNotEqual(a, a2);
            Assert.AreNotEqual(b, b2);
            Assert.AreNotEqual(a1, a2);
            Assert.AreNotEqual(b1, b2);


        }
    }

    [TestMethod]
    public void 多类型没有瞬态服务()
    {
        var services = new ServiceCollection()
            .AddComponents([typeof(MyClass1)])
            .BuildServiceProvider();
        using (var scope = services.CreateScope())
        {
            var a = services.GetService<MyClass>();
            var b = scope.ServiceProvider.GetService<MyClass>();
            var c = services.GetService<MyClass>();
            var d = scope.ServiceProvider.GetService<MyClass>();
            Assert.AreNotEqual(a, b);
            Assert.AreEqual(a, c);
            Assert.AreEqual(b, d);


            var a1 = services.GetService<MyClass1>();
            var b1 = scope.ServiceProvider.GetService<MyClass1>();
            var c1 = services.GetService<MyClass1>();
            var d1 = scope.ServiceProvider.GetService<MyClass1>();
            Assert.AreNotEqual(a1, b1);
            Assert.AreEqual(a1, c1);
            Assert.AreEqual(b1, d1);

            Assert.AreEqual(a, a1);
        }
    }





    [SingletonComponent]
    [ScopedComponent]
    [SingletonComponent(typeof(MyClass))]
    [ScopedComponent(typeof(MyClass))]

    [SingletonComponent(Key = "1")]
    [ScopedComponent(Key = "1")]
    [SingletonComponent(typeof(MyClass), Key = "1")]
    [ScopedComponent(typeof(MyClass), Key = "1")]

    [SingletonComponent(Key = "2")]
    [ScopedComponent(Key = "2")]
    [SingletonComponent(typeof(MyClass), Key = "2")]
    [ScopedComponent(typeof(MyClass), Key = "2")]

    class MyClass1(IServiceProvider services) : MyClass(services);
    [DebuggerDisplay("{Id}")]
    class MyClass(IServiceProvider services)
    {
        private static long _id = 0;
        public long Id { get; } = Interlocked.Increment(ref _id);
        public IServiceProvider Services { get; } = services;

        public bool IsRoot
        {
            get
            {
                var x = Services.GetService<SingletonServiceProvider>();
                return Services == x.GetService<IServiceProvider>();
            }
        }
    }

}
